/*
 *  Math.h
 *  NSE_SOLVER
 *
 *  Created by Patrick Zulian on 12/22/10.
 *  Copyright 2010 ICS - USI - Lugano. All rights reserved.
 *
 */


#ifndef NSE_SOLVER_MATH_H
#define NSE_SOLVER_MATH_H

#include <math.h>
#include <iostream>

#include "Base.h"

namespace nsesolver {
	
	class Math {
	private:
		/**
		 * Positive Integer Power computed at compile time
		 */
		template< int X, int Exp >
		struct PowAux
		{
			enum { result = X*PowAux< X, Exp - 1>::result };
		};
		
		template< int X >
		struct PowAux< X, 0 >
		{
			enum { result = 1 };
		};
		
		template< int X >
		struct PowAux< X, 1 >
		{
			enum { result = X };
		};
		
		
	public: 
		template< int X, int Exp >
		inline static int Pow()
		{
			NSE_SOLVER_ASSERT(Exp >= 0);
			return PowAux< X, Exp >::result;
		}
		
		template< typename T >
		inline static T Pow(T base,  T exponent)
		{
			return pow(base, exponent);
		}
		
		template< typename T >
		inline static T Pow(T base, int exponent)
		{
			T result = 1.0;
			for (int e = 0; e < exponent; ++e) {
				result *= base;
			}
			return result;
		}

		inline static int Pow(int base, int exponent)
		{
			int result = 1;
			for (int e = 0; e < exponent; ++e) {
				result *= base;
			}
			
			NSE_SOLVER_ASSERT(result == (int) pow(base, exponent));
			return result;
		}
		
		
		template< typename T >
        static T identity()
		{
			return static_cast< T >(1);
		}
		
		template< typename T >
		static T zero()
		{
			return static_cast< T >(0);
		}
		
		
		template< typename T >
		static T abs(const T x)
		{
			return ( x < zero< T >() )? ( -identity< T >() ) * x : x;
		}
		
		template< typename T >
		static T Pi()
		{
			return static_cast< T > (3.141592653589793238462643383279502884197169399375105820974944592307816406286);
		}
		
	};
	

	
	
}

#endif
